package com.legal.memory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.legal.domain.entity.Msg;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;

/**
 * 基于Redis实现的聊天记忆存储
 * 实现了Spring AI的 ChatMemory接口，用于存储和Spring AI根据chatId检索聊天消息历史
 */
@RequiredArgsConstructor
public class RedisChatMemory implements ChatMemory {

    // Redis操作模板
    private final StringRedisTemplate redisTemplate;
    // JSON序列化工具
    private final ObjectMapper objectMapper;
    // Redis键前缀，用于区分不同类型的键
    private final static String PREFIX = "legal:message:";

    /**
     * 添加消息到聊天记忆
     * @param conversationId 会话ID，用于区分不同对话
     * @param messages 要添加的消息列表
     */
    @Override
    public void add(String conversationId, List<Message> messages) {
        // 如果消息列表为空，直接返回
        if (messages == null || messages.isEmpty()) {
            return;
        }
        // 将Message对象转换为Msg对象，然后序列化为JSON字符串
        List<String> list = messages.stream().map(Msg::new).map(msg -> {
            // 处理text字段，截取"end"之前的内容
            if (msg.getText() != null) {
                String text = msg.getText();
                int endIndex = text.indexOf("end");
                if (endIndex != -1) {
                    // 截取"end"之前的内容，并去除末尾的空白字符
                    msg.setText(text.substring(0, endIndex).trim());
                }
            }
            try {
                return objectMapper.writeValueAsString(msg);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }).toList();
        // 将消息列表存入Redis，使用左推方式（最新消息在列表头部）
        redisTemplate.opsForList().leftPushAll(PREFIX + conversationId, list);
    }

    /**
     * 从聊天记忆中获取指定数量的最近消息
     * @param conversationId 会话ID
     * @param lastN 要获取的消息数量
     * @return 消息列表，如果没有消息则返回空列表
     */
    @Override
    public List<Message> get(String conversationId, int lastN) {
        // 从Redis获取指定范围的聊天记录（从0到lastN-1）
        List<String> list = redisTemplate.opsForList().range(PREFIX + conversationId, 0, lastN);
        // 如果结果为空，返回空列表
        if (list == null || list.isEmpty()) {
            return List.of();
        }
        // 将JSON字符串反序列化为Msg对象，再转换为Message对象
        return list.stream().map(s -> {
            try {
                return objectMapper.readValue(s, Msg.class);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }).map(Msg::toMessage).toList();
    }

    /**
     * 清除指定会话的聊天记忆
     * @param conversationId 要清除的会话ID
     */
    @Override
    public void clear(String conversationId) {
        // 从Redis删除指定会话的键
        redisTemplate.delete(PREFIX + conversationId);
    }
}